MethodsParser.js ➔ ... ➔ ???
last analyzed

Size

Total Lines 76

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 4
Metric Value
c 4
b 0
f 4
nc 8
dl 0
loc 76
ccs 27
cts 29
cp 0.931
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1 1
const ParserInterface  = require('../ParserInterface'),
2
      _                = require('lodash'),
3
      ParametersParser = require('./ParametersParser'),
4
      ResponseParser   = require('./ResponseParser')
5
6
/**
7
 * @ignore _
8
 */
9
10
/**
11
 * Methods parser for swagger 2.0
12
 * @class MethodsParser
13
 *
14
 * @property {Object} methods Original methods data
15
 * @property {ResponseParser|undefined} respParser Response parser object
16
 * @property {ParametersParser|undefined} paramParser Parameters parser object
17
 * @property {SecuritySchemesParser} securityParser Security parser
18
 * @property {ParameterParserOptionsObject} parameterParserConfig Parameters parser config object
19
 * @property {Array.<MethodConfigObject>} parseMethods Parsed methods
20
 * @property {Array.<String>.<MethodConfigObject>} methodsGroup Grouping parsed methods
21
 * @property {String} packageName Package name
22
 * @property {String} className Class name
23
 * @property {String} moduleName Module name
24
 */
25
class MethodsParser extends ParserInterface {
26
  constructor (methods, securityParser, definitions, options) {
27 2
    super()
28
29 2
    options = options || {}
30
31 2
    this.parameterParserConfig = options.parameterParserConfig
32
    // this.respParserConfig = options.respParserConfig
33
34 2
    this.moduleName  = options.moduleName
35 2
    this.className   = options.className
36 2
    this.packageName = options.packageName
37
38 2
    this.securityParser = securityParser
39 2
    this.parseMethods   = []
40 2
    this.definitions    = definitions
41 2
    this.methods        = methods
42 2
    this.modelPath      = options.modelPath
43 2
    this.docsPath       = options.docsPath
44 2
    this.methodsGroup   = {}
45
  }
46
47
  _iterateMethod (config, uri, definitions) {
48 2
    let _self = this
49 2
    _.each(config, (methodConfig, method) => {
50 2
      method         = _.upperCase(method)
51 2
      let nextMethod = {
52
        path          : uri,
53
        method        : method,
54
        methodName    : methodConfig.operationId ? MethodsParser._normalizeMethodName(methodConfig.operationId) : MethodsParser._getPathToMethodName(config, method, uri),
55
        tags          : methodConfig.tags,
56
        summary       : methodConfig.summary,
57
        description   : methodConfig.description,
58
        externalDocs  : methodConfig.externalDocs,
59
        operationId   : methodConfig.operationId,
60
        produces      : methodConfig.produces,
61
        consumes      : methodConfig.consumes,
62
        schemes       : methodConfig.schemes,
63
        isDeprecated  : methodConfig.deprecated || false,
64
        security      : methodConfig.security,
65
        isSecure      : typeof methodConfig.security !== 'undefined',
66
        isGET         : method === 'GET',
67
        isPUT         : method === 'PUT',
68
        isOPTIONS     : method === 'OPTIONS',
69
        isDELETE      : method === 'DELETE',
70
        isHEAD        : method === 'HEAD',
71
        isPOST        : method === 'POST',
72
        isTRACE       : method === 'TRACE',
73
        isCONNECT     : method === 'CONNECT',
74
        isPATCH       : method === 'PATCH',
75
        definitions   : this.definitions || {},
76
        headers       : [],
77
        parameters    : [],
78
        bodyParams    : [],
79
        queryParams   : [],
80
        formDataParams: [],
81
        enums         : [],
82
        pathParams    : [],
83
        modelPath     : _self.modelPath,
84
        docsPath      : _self.docsPath
85
      }
86
87 2
      if (_.size(methodConfig.parameters)) {
88 1
        _self.paramParser         = new ParametersParser(methodConfig.parameters, _self.parameterParserConfig)
89 1
        nextMethod.parameters     = _self.paramParser.parse()
90 1
        nextMethod.headers        = _self.paramParser.headers
91 1
        nextMethod.enums          = _self.paramParser.enums
92 1
        nextMethod.bodyParams     = _self.paramParser.bodys
93 1
        nextMethod.queryParams    = _self.paramParser.querys
94 1
        nextMethod.formDataParams = _self.paramParser.formDatas
95 1
        nextMethod.pathParams     = _self.paramParser.paths
96
      }
97
98 2
      if (_.size(methodConfig.responses)) {
99
        _self.respParser     = new ResponseParser(methodConfig.responses, this.modelPath)
100
        nextMethod.responses = _self.respParser.parse()
101
      }
102
103 2
      nextMethod             = _self._addSecurityParameters(nextMethod)
104 2
      nextMethod.packageName = _self.packageName
105 2
      nextMethod.className   = _self.className
106 2
      nextMethod.moduleName  = _self.moduleName
107 2
      nextMethod.docsPath    = _self.docsPath
108 2
      nextMethod.modelPath   = _self.modelPath
109 2
      nextMethod.definitions = _self.definitions
110
111 2
      if (nextMethod.tags) {
112 2
        let tags = nextMethod.tags
113 2
        for (let i = 0; i < tags.length; i++) {
114 2
          if (typeof this.methodsGroup[tags[i]] === 'undefined') {
115 2
            this.methodsGroup[tags[i]] = []
116
          }
117
118 2
          this.methodsGroup[tags[i]].push(nextMethod)
119
        }
120
      }
121
122 2
      _self.parseMethods.push(nextMethod)
123
124
    })
125
  }
126
127
  /**
128
   * Normalize method name
129
   *
130
   * @return {string}
131
   *
132
   * @private
133
   */
134
  static _normalizeMethodName (id) {
135
    /* eslint-disable */
136
    return id.replace(/\.|\-|\{|\}/g, '_').split(' ').join('_')
137
    /* eslint-enable */
138
  }
139
140
  /**
141
   *
142
   * @param {Object} opts
143
   * @param m
144
   * @param path
145
   * @return {*}
146
   * @private
147
   */
148
  static _getPathToMethodName (opts, m, path) {
149 4
    if (path === '/' || path === '') {
150
      return m
151
    }
152
153
    // clean url path for requests ending with '/'
154 2
    let cleanPath = path.replace(/\/$/, '')
155
156 2
    let segments = cleanPath.split('/').slice(1)
157 2
    segments     = _.transform(segments, function (result, segment) {
158 6
      if (segment[0] === '{' && segment[segment.length - 1] === '}') {
159
        segment = 'by' + segment[1].toUpperCase() + segment.substring(2, segment.length - 1)
160
      }
161 6
      result.push(segment)
162
    })
163 2
    let result   = _.camelCase(segments.join('-'))
164 2
    return m.toLowerCase() + result[0].toUpperCase() + result.substring(1)
165
  }
166
167
  /**
168
   * Add security headers & params
169
   *
170
   * @param {MethodConfigObject} methodConfig
171
   *
172
   * @return {MethodConfigObject}
173
   * @private
174
   */
175
  _addSecurityParameters (methodConfig) {
176 2
    let headers    = this.securityParser.getHeadersForRequest(methodConfig.security),
177
        parameters = this.securityParser.getParametersForRequest(methodConfig.security)
178
179 2
    if (_.size(headers)) {
180
      _.each(headers, (headConfig) => {
181 2
        if (typeof headConfig === 'undefined') {
182
          return
183
        }
184
        methodConfig.headers.push(headConfig)
185
      })
186
    }
187
188 2
    if (_.size(parameters)) {
189
      _.each(parameters, (paramConfig, index) => {
0 ignored issues
show
Unused Code introduced by
The parameter index is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
190 2
        if (typeof paramConfig === 'undefined') {
191
          return
192
        }
193
        methodConfig.parameters.push(paramConfig)
194 2
        if (paramConfig.in) {
195 2
          if (typeof methodConfig.parameters[paramConfig.in + 'Params'] === 'undefined') {
196
            throw new Error('Unsupported operand. Send issue please about error')
197
          }
198
          methodConfig.parameters[paramConfig.in + 'Params'].push(paramConfig)
199
        }
200
      })
201
    }
202
203 2
    return methodConfig
204
  }
205
206
  /**
207
   * Parse methods data
208
   *
209
   * @property {Array.<Swagger20OperationDefinition>} definitions
210
   *
211
   * @return {Array.<MethodConfigObject>}
212
   */
213
  parse (definitions) {
214 2
    let _self = this
215
216 2
    _.each(this.methods, (config, uri) => {
217 2
      _self._iterateMethod(config, uri, definitions)
218
    })
219
220 2
    return this.parseMethods
221
  }
222
}
223
224
/**
225
 * @ignore module.exports
226
 * @ignore exports
227
 */
228
module.exports = MethodsParser